home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / lbmake / lbmake.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  21KB  |  1,109 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  Second generation library maker.  Gets library information from lib.def
  9.  *  file in current directory
  10.  *
  11.  *  LBMAKE [keywords] [types]
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #ifndef LATTICE
  19. #include <lists.h>
  20. #endif
  21. #include <exec/types.h>
  22. #ifndef LATTICE
  23. #include <sys/stat.h>
  24.  
  25. #ifdef unix
  26. #include <../suplib/memory.h>
  27. #else
  28. #include <dos/dos.h>
  29. #include <clib/dos_protos.h>
  30. #include <clib/exec_protos.h>
  31. #include <clib/alib_protos.h>
  32. #endif
  33. #include <lib/version.h>
  34. #else
  35. #include <libraries/dos.h>
  36. #include <proto/dos.h>
  37. #include <proto/exec.h>
  38. #endif
  39.  
  40. #define arysize(ary)    (sizeof(ary)/sizeof((ary)[0]))
  41.  
  42. #define KT_TYPE     0
  43. #define KT_LIBRARY  1
  44. #define KT_OBJECT   3
  45. #define KT_ALTTREE  4
  46. #define KT_OPTION   5
  47.  
  48. typedef struct Node Node;
  49. typedef struct List List;
  50. typedef struct FileInfoBlock FileInfoBlock;
  51.  
  52. typedef struct KeyNode {
  53.     Node    kn_Node;
  54.     char    *kn_Data;
  55.     char    *kn_Obj;        /*    file list only            */
  56.     char    *kn_Aux;        /*    file list only            */
  57.     short   kn_Option;        /*    -1 loose, 0 ignore, 1 use   */
  58.     short   kn_Flags;
  59. } KeyNode;
  60.  
  61. #define KF_COMPILED    0x0001
  62. #define KF_ERROR    0x0002
  63.  
  64. typedef struct CmdNode {
  65.     char    *cn_Name;        /*    name of command */
  66.     short   cn_Args;        /*    number of args    */
  67.     short   cn_Id;
  68.     int     (*cn_Func)(short, char **, short, long);
  69. } CmdNode;
  70.  
  71. void    help(int);
  72. KeyNode *FindKeyNode(KeyNode *, char *);
  73. KeyNode *FindOptionNode(KeyNode *, char *);
  74. int    CompileStuff(KeyNode *);
  75. int    JoinStuff(KeyNode *, int);
  76. int    ScanLibDefFile(void);
  77. int    ProcessCommandLine(int, char *, long);
  78. int    ProcessFileLine(int, char *, long);
  79. KeyNode* AllocKeyNode(char *, char *, char *, char *);
  80.  
  81. int    CmdAddKey(short, char **, short, long);
  82. int    CmdType(short, char **, short, long);
  83. int    CmdDefTree(short, char **, short, long);
  84.  
  85. int    Assemble(KeyNode *fn, char *, char *);
  86. int    AssembleA68(KeyNode *fn, char *, char *);
  87. int    FDToLib(char *, char *, char *);
  88. int    Compile(char *, char *);
  89.  
  90. int    strreplace(char *, char *, char *);
  91.  
  92. int    CompareTimeStamps(char *, char *);
  93. void    CreateDirPath(char *);
  94. char    *FillName(char *, char **, char *);
  95. void    DicePrefix(char *, char *, char *);
  96. char    *FilterFile(char *);
  97.  
  98. #ifdef LATTICE
  99. void    *GetHead(List *);
  100. void    *GetSucc(Node *);
  101. #endif
  102.  
  103. CmdNode CmdAry[] = {
  104.     {    "Objects",  2,  KT_OBJECT , CmdAddKey   },
  105.     {    "Library",  2,  KT_LIBRARY, CmdAddKey   },
  106.     {    "Type"   ,  -1, KT_TYPE   , CmdType     },
  107.     {    "DefTree",  1,  0         , CmdDefTree  },
  108.     {    "AltTree",  2,  KT_ALTTREE, CmdAddKey   },
  109.     {    "Option",   -1, KT_OPTION , CmdAddKey   }
  110. };
  111.  
  112. List    KeyList;
  113. List    FileList;
  114. char    CompilerName[64];
  115. char    FDToLibName[64];
  116. char    FlagsBuf[256];
  117. char    TypeBuf[256];
  118. char    DefTree[256];
  119. char    TmpBuf[8192];
  120. char    LastPath[256];
  121.  
  122. short    DoNotExecute =0;
  123. short    Verbose = 0;
  124. short    Symbols = 1;
  125.  
  126. int _DiceCacheEnable = 1;
  127.  
  128. #ifdef _DCC
  129. IDENT("lbmake",".3");
  130. DCOPYRIGHT;
  131. #endif
  132.  
  133. main(ac, av)
  134. char *av[];
  135. {
  136.     short i;
  137.     short j;
  138.     int r = 0;
  139.  
  140.     NewList(&KeyList);
  141.     NewList(&FileList);
  142.  
  143.     DicePrefix(CompilerName, av[0], "dcc");
  144.     DicePrefix(FDToLibName, av[0], "fdtolib");
  145.  
  146.     if (ac == 1)
  147.     help(0);
  148.  
  149.     if (ScanLibDefFile() < 0)
  150.     help(10);
  151.  
  152.     for (i = 1; i < ac; ++i) {
  153.     char *ptr = av[i];
  154.     short option;
  155.     KeyNode *kn;
  156.  
  157.     switch(*ptr) {
  158.     case '-':
  159.         if (strcmp(ptr, "-nosym") == 0) {
  160.         Symbols = 0;
  161.         continue;
  162.         }
  163.  
  164.         if (strcmp(ptr, "-n") == 0) {
  165.         DoNotExecute = 1;
  166.         continue;
  167.         }
  168.         if (strcmp(ptr, "-v") == 0) {
  169.         Verbose = 1;
  170.         continue;
  171.         }
  172.  
  173.         option = -1;
  174.         ++ptr;
  175.         break;
  176.  
  177.     case '+':
  178.         ++ptr;
  179.     default:
  180.         option = 1;
  181.         break;
  182.     }
  183.     for (kn = NULL, j = 0; kn = FindKeyNode(kn, ptr); ++j)
  184.         kn->kn_Option = option;
  185.     for (kn = NULL; kn = FindOptionNode(kn, ptr); ++j) {
  186.         if (kn->kn_Option == 0)
  187.         kn->kn_Option = option;
  188.     }
  189.     if (j == 0) {
  190.         printf("Unable to find symbol %s\n", ptr);
  191.         r = 10;
  192.     }
  193.     }
  194.  
  195.     /*
  196.      *    Handle compilation flags
  197.      *    Handle alternate object tree
  198.      *    Select compiler
  199.      */
  200.  
  201.     {
  202.     KeyNode *kn;
  203.     for (kn = GetHead(&KeyList); kn; kn = GetSucc(&kn->kn_Node)) {
  204.         if (kn->kn_Option <= 0)
  205.         continue;
  206.  
  207.         switch(kn->kn_Node.ln_Type) {
  208.         case KT_TYPE:
  209.         strcat(FlagsBuf, kn->kn_Data);
  210.         strcat(FlagsBuf, " ");
  211.         strcat(TypeBuf, kn->kn_Node.ln_Name);
  212.         break;
  213.         case KT_ALTTREE:
  214.         strcpy(DefTree, kn->kn_Data);
  215.         break;
  216.         default:
  217.         break;
  218.         }
  219.     }
  220.     }
  221.  
  222.     /*
  223.      *    Create destination tree
  224.      */
  225.  
  226.     sprintf(TmpBuf, DefTree, TypeBuf);
  227.     CreateDirPath(TmpBuf);
  228.  
  229.     /*
  230.      *    Scan for objects to create and libraries to make
  231.      */
  232.  
  233.     {
  234.     KeyNode *kn;
  235.     for (kn = GetHead(&KeyList); r == 0 && kn; kn = GetSucc(&kn->kn_Node)) {
  236.         if (kn->kn_Option <= 0)
  237.         continue;
  238.  
  239.         switch(kn->kn_Node.ln_Type) {
  240.         case KT_OBJECT:
  241.         case KT_LIBRARY:
  242.         r = CompileStuff(kn);    /*  < 0 error, == 0 need to link, 1 no work */
  243.         if (r >= 0 && DoNotExecute == 0)
  244.             r = JoinStuff(kn, r);
  245.         break;
  246.         default:
  247.         break;
  248.         }
  249.         if (r < 0)
  250.         break;
  251.     }
  252.     }
  253.     if (r < 0)
  254.     r = 20;
  255.     return(r);
  256. }
  257.  
  258. void
  259. help(code)
  260. {
  261.     puts("LBMAKE [keywords types]");
  262.     exit(code);
  263. }
  264.  
  265. KeyNode *
  266. FindKeyNode(kn, name)
  267. KeyNode *kn;
  268. char *name;
  269. {
  270.     for (kn = ((kn) ? GetSucc(&kn->kn_Node) : GetHead(&KeyList)); kn; kn = GetSucc(&kn->kn_Node)) {
  271.     if (stricmp(name, kn->kn_Node.ln_Name) == 0)
  272.         break;
  273.     }
  274.     return(kn);
  275. }
  276.  
  277. KeyNode *
  278. FindOptionNode(kn, name)
  279. KeyNode *kn;
  280. char *name;
  281. {
  282.     short len = strlen(name);
  283.  
  284.     for (kn = ((kn) ? GetSucc(&kn->kn_Node) : GetHead(&FileList)); kn; kn = GetSucc(&kn->kn_Node)) {
  285.     char *ptr;
  286.  
  287.     for (ptr = kn->kn_Data; *ptr; ++ptr) {
  288.         if (*ptr == '+' || *ptr == '-') {
  289.         short l2;
  290.         {
  291.             short c;
  292.             for (l2 = 0; c = ptr[l2]; ++l2) {
  293.             if (c == ' ' || c == '\t' || c == '\n')
  294.                 break;
  295.             }
  296.         }
  297.         if (len == l2 - 1 && strnicmp(ptr + 1, name, len) == 0) {
  298.             if (*ptr == '-')
  299.             kn->kn_Option = -1;
  300.             return(kn);
  301.         }
  302.         }
  303.     }
  304.     }
  305.     return(NULL);
  306. }
  307.  
  308. /*
  309.  *  Compile a library or object group, scan file list for files to do
  310.  *  things to.    Base the action on their tailer:
  311.  *
  312.  *    .a    assemble with DAS
  313.  *    .asm    assemble with A68K
  314.  *    .a68    assemble with A68K
  315.  *    .fd    generate using FDTOLIB
  316.  *    .lib    copy
  317.  *    .o    copy
  318.  *    .c    compile
  319.  *    <other> error
  320.  */
  321.  
  322. int
  323. CompileStuff(kn)
  324. KeyNode *kn;
  325. {
  326.     KeyNode *fn;
  327.     char *ptr;
  328.     char buf[128];
  329.     char obj[128];
  330.     int r = 1;
  331.  
  332.     printf("Compile Stuff %s: %s\n", kn->kn_Node.ln_Name, kn->kn_Data);
  333.  
  334.     sprintf(buf, "+%s", kn->kn_Node.ln_Name);
  335.  
  336.     for (fn = GetHead(&FileList); r >= 0 && fn; fn = GetSucc(&fn->kn_Node)) {
  337.     if (fn->kn_Option <= 0)
  338.         continue;
  339.     if (strstr(fn->kn_Data, buf) == NULL)
  340.         continue;
  341.  
  342.     if(Verbose)printf("Examining %s (%s)\n",fn->kn_Node.ln_Name, fn->kn_Obj);
  343.  
  344.     {
  345.         int n;
  346.  
  347.         if (strchr(fn->kn_Obj, ':')) n = 0;
  348.         else n = sprintf(obj, DefTree, TypeBuf);
  349.  
  350. //        strcpy(obj + n, fn->kn_Obj);
  351.         strcat(obj,fn->kn_Obj);
  352.  
  353.  
  354.         if (ptr = strrchr(obj, '/')) {
  355.         *ptr = 0;
  356.         if (strcmp(obj, LastPath) != 0) {
  357.             CreateDirPath(obj);
  358.             strcpy(LastPath, obj);
  359.         }
  360.         *ptr = '/';
  361.         }
  362.     }
  363.  
  364.     /*
  365.      *  check timestamp. returns -1, 0, 1 as in strcmp(), but also returns
  366.      *  -1 if either file does not exist
  367.      */
  368.     if (CompareTimeStamps(obj, fn->kn_Node.ln_Name) < 0) {
  369.         if(Verbose)printf("Compiling/assembling.\n");
  370.         if (r > 0)
  371.         r = 0;
  372.  
  373.         if (ptr = strrchr(fn->kn_Node.ln_Name, '.')) {
  374.         if (stricmp(ptr, ".asm") == 0)
  375.             r = AssembleA68(fn, fn->kn_Node.ln_Name, obj);
  376.         else if (stricmp(ptr, ".a68") == 0)
  377.             r = AssembleA68(fn, fn->kn_Node.ln_Name, obj);
  378.         else if (stricmp(ptr, ".a") == 0)
  379.             r = Assemble(fn, fn->kn_Node.ln_Name, obj);
  380.         else if (stricmp(ptr, ".fd") == 0)
  381.             r = FDToLib(fn->kn_Node.ln_Name, obj, fn->kn_Aux);
  382.         else if (stricmp(ptr, ".lib") == 0 || stricmp(ptr, ".o") == 0)
  383.             r = 0;
  384.         else
  385.             r = Compile(fn->kn_Node.ln_Name, obj);
  386.         }
  387.         else {
  388.         r = Compile(fn->kn_Node.ln_Name, obj);
  389.         }
  390.  
  391.         /*
  392.          *    If an error occured quit out
  393.          */
  394.  
  395.         if (r > 5)
  396.         r = -r;
  397.         if (r < 0)
  398.         break;
  399.     }
  400.     else {
  401.         if(Verbose)printf("Is up to date.\n");
  402.     }
  403.     }
  404.     return(r);
  405. }
  406.  
  407. /*
  408.  *  JoinStuff()
  409.  *
  410.  *  join objects into the destination library
  411.  */
  412.  
  413. int
  414. JoinStuff(kn, need)
  415. KeyNode *kn;
  416. int need;
  417. {
  418.     KeyNode *fn;
  419.     FILE *fi = NULL;
  420.     FILE *fj;
  421.     char buf[128];
  422.     static char src[128];
  423.     static char dst[128];
  424.     int r = 0;
  425.  
  426.     /*
  427.      *    compute library name
  428.      */
  429.     if (kn->kn_Node.ln_Type == KT_LIBRARY) {
  430.     sprintf(buf, kn->kn_Data, TypeBuf);
  431.     if (need > 0 && (fi = fopen(buf, "r"))) {
  432.         printf("UpToDate: %s\n", buf);
  433.         fclose(fi);
  434.         return(0);
  435.     }
  436.     if (fi = fopen(buf, "w")) {
  437.         printf("Create %s\n", buf);
  438.     } else {
  439.         printf("Unable to create %s\n", buf);
  440.         return(-1);
  441.     }
  442.     }
  443.  
  444.     /*
  445.      *    append object modules
  446.      */
  447.  
  448.     sprintf(buf, "+%s", kn->kn_Node.ln_Name);
  449.     for (fn = GetHead(&FileList); r == 0 && fn; fn = GetSucc(&fn->kn_Node)) {
  450.     if (fn->kn_Option <= 0)
  451.         continue;
  452.     if (strstr(fn->kn_Data, buf) == NULL)
  453.         continue;
  454.  
  455.     {
  456.         int n;
  457.         if (strchr(fn->kn_Obj, ':'))
  458.         n = 0;
  459.         else
  460.         n = sprintf(src, DefTree, TypeBuf);
  461.         strcpy(src + n, fn->kn_Obj);
  462.     }
  463.  
  464.     if (kn->kn_Node.ln_Type == KT_OBJECT) {
  465.         char *ptr = fn->kn_Obj + strlen(fn->kn_Obj);
  466.         while (ptr >= fn->kn_Obj && *ptr != ':' && *ptr != '/')
  467.         --ptr;
  468.         sprintf(dst, kn->kn_Data, ptr + 1, TypeBuf);
  469.         if (CompareTimeStamps(dst, src) >= 0) {
  470.         printf("UpToDate: %s\n", dst);
  471.         continue;
  472.         }
  473.  
  474.         fi = fopen(dst, "w");
  475.         printf("Create %s\n", dst);
  476.     }
  477.  
  478.  
  479.     if (fj = fopen(src, "r")) {
  480.         long n;
  481.         while ((n = fread(TmpBuf, 1, sizeof(TmpBuf), fj)) > 0) {
  482.         if (fi) {
  483.             if (fwrite(TmpBuf, 1, n, fi) != n) {
  484.             puts("write error");
  485.             r = -1;
  486.             break;
  487.             }
  488.         }
  489.         }
  490.         fclose(fj);
  491.     } else {
  492.         printf("Unable to open %s\n", src);
  493.         r = -1;
  494.     }
  495.     if (kn->kn_Node.ln_Type == KT_OBJECT && fi) {
  496.         fclose(fi);
  497.         fi = NULL;
  498.     }
  499.     }
  500.     if (fi)
  501.     fclose(fi);
  502.     return(r);
  503. }
  504.  
  505. int
  506. ScanLibDefFile()
  507. {
  508.     FILE *fi;
  509.     char *ptr;
  510.     char buf[256];
  511.     int r = 0;
  512.     short lineNo = 0;
  513.     char *libDefName = getenv("LIBDEF") ? getenv("LIBDEF") : "lib.def";
  514.  
  515.     if (fi = fopen(libDefName, "r")) {
  516.     while (fgets(buf, sizeof(buf), fi)) {
  517.         ++lineNo;
  518.         for (ptr = buf; *ptr == ' ' || *ptr == '\t'; ++ptr);
  519.  
  520.         if (*ptr == '\n' || *ptr == '#')
  521.         continue;
  522.  
  523.         if (*ptr == '@') {
  524.         r = ProcessCommandLine(r, ptr, lineNo);
  525.         } else {
  526.         r = ProcessFileLine(r, ptr, lineNo);
  527.         }
  528.     }
  529.     fclose(fi);
  530.     } else {
  531.     printf("Unable to open lib.def\n");
  532.     r = -1;
  533.     }
  534.     return(r);
  535. }
  536.  
  537. int
  538. ProcessCommandLine(r, cmd, line)
  539. int r;
  540. char *cmd;
  541. long line;
  542. {
  543.     static char *av[64];
  544.     short ac;
  545.  
  546.     if (cmd = strtok(cmd + 1, " \t\n")) {
  547.     CmdNode *cn;
  548.     for (cn = CmdAry; cn < CmdAry + arysize(CmdAry); ++cn) {
  549.         if (stricmp(cmd, cn->cn_Name) == 0)
  550.         break;
  551.     }
  552.     for (ac = 0; ac < 64 && (av[ac] = strtok(NULL, " \t\n")); ++ac)
  553.         ;
  554.     if (cn) {
  555.         if (cn->cn_Args >= 0 && ac != cn->cn_Args) {
  556.         printf("Expected %d args for %s line %d\n", cn->cn_Args, cmd, line);
  557.         r = -1;
  558.         } else {
  559.         if (cn->cn_Func(ac, av, cn->cn_Id, line) < 0)
  560.             r = -1;
  561.         }
  562.     } else {
  563.         printf("Unknown @ command line %d (%s)\n", line, cmd);
  564.         r = -1;
  565.  
  566.     }
  567.     } else {
  568.     printf("Bad @ command line %d\n", line);
  569.     r = -1;
  570.     }
  571.     return(r);
  572. }
  573.  
  574. int
  575. ProcessFileLine(r, ptr, line)
  576. int r;
  577. char *ptr;
  578. long line;
  579. {
  580.     KeyNode *kn;
  581.     char *opts;
  582.     short i;
  583.     short j;
  584.     static char src[256];
  585.     static char obj[256];
  586.     static char aux[256];
  587.  
  588.     while (*ptr == ' ' || *ptr == '\t')
  589.     ++ptr;
  590.  
  591.     for (i = 0; ptr[i] && ptr[i] != ' ' && ptr[i] != '\t'; ++i) {
  592.     /*
  593.      *  Handle a comma (separator between filepathname and
  594.      *  auxillary information (e.g. library name for .fd files)
  595.      */
  596.     if (ptr[i] == ',')
  597.         break;
  598.     }
  599.  
  600.     strncpy(src, ptr, i);
  601.     src[i] = 0;
  602.  
  603.     strcpy(obj, src);
  604.  
  605.     aux[0] = 0;
  606.     if (ptr[i] == ',') {
  607.     ++i;
  608.     for (opts = ptr + i; *opts && *opts != ' ' && *opts != '\t'; ++opts)
  609.         ;
  610.     strncpy(aux, ptr + i, opts - (ptr + i));
  611.     aux[opts - (ptr + i)] = 0;
  612.     } else {
  613.     opts = ptr + i;
  614.     }
  615.     if (*opts == 0) {
  616.     printf("File Line Error, no keywords: %s", ptr);
  617.     return(-1);
  618.     }
  619.     for (; *opts == ' ' || *opts == '\t'; ++opts)
  620.     ;
  621.  
  622.     /*
  623.      *    remove '[' and ']' from source name
  624.      */
  625.  
  626.     for (i = j = 0; src[i]; ++i) {
  627.     switch(src[i]) {
  628.     case '[':
  629.     case ']':
  630.         break;
  631.     default:
  632.         src[j] = src[i];
  633.         ++j;
  634.         break;
  635.     }
  636.     }
  637.     src[j] = 0;
  638.  
  639.     /*
  640.      *    remove [path] from object name
  641.      */
  642.  
  643.  
  644.     for (ptr = strchr(obj, '['); ptr; ptr = strchr(ptr, '[')) {
  645.     char *p2;
  646.     if (p2 = strchr(ptr, ']')) {
  647.         movmem(p2 + 1, ptr, strlen(p2));
  648.     } else {
  649.         printf("No matching ']' on line %d\n", line);
  650.         return(-1);
  651.     }
  652.     }
  653.  
  654.     /*
  655.      *    modify tail to .o if not already a .lib or .o
  656.      */
  657.  
  658.     if (ptr = strrchr(obj, '.')) {
  659.     if (stricmp(ptr, ".lib") != 0 && stricmp(ptr, ".o") != 0)
  660.         strcpy(ptr, ".o");
  661.     } else {
  662.     strcat(ptr, ".o");
  663.     }
  664.  
  665.     kn = AllocKeyNode(src, opts, obj, (aux[0] ? aux : NULL));
  666.  
  667.     AddTail(&FileList, &kn->kn_Node);
  668.  
  669.     return(r);
  670. }
  671.  
  672. int
  673. CmdAddKey(short ac, char **av, short id, long line)
  674. {
  675.     KeyNode *kn = AllocKeyNode(av[0], av[1], NULL, NULL);
  676.     kn->kn_Node.ln_Type = id;
  677.     AddTail(&KeyList, &kn->kn_Node);
  678.     return(0);
  679. }
  680.  
  681. int
  682. CmdType(short ac, char **av, short id, long line)
  683. {
  684.     short i;
  685.  
  686.     if (ac == 0) {
  687.     printf("Expected type designator line %d\n", line);
  688.     return(-1);
  689.     }
  690.     for (i = 1, TmpBuf[0] = 0; i < ac; ++i) {
  691.     if (i > 1)
  692.         strcat(TmpBuf, " ");
  693.     strcat(TmpBuf, av[i]);
  694.     }
  695.     av[1] = TmpBuf;
  696.     return(CmdAddKey(ac, av, id, line));
  697. }
  698.  
  699. int
  700. CmdDefTree(short ac, char **av, short id, long line)
  701. {
  702.     strcpy(DefTree, av[0]);
  703.     return(0);
  704. }
  705.  
  706. KeyNode *
  707. AllocKeyNode(name1, name2, objName, auxName)
  708. char *name1;
  709. char *name2;
  710. char *objName;
  711. char *auxName;
  712. {
  713.     static char   *AlBuf;
  714.     static long   AlBytes;
  715.     KeyNode *kn;
  716.     long bytes = sizeof(KeyNode) + 2 + strlen(name1) + strlen(name2);
  717.     char *fillPtr;
  718.  
  719.     if (objName)
  720.     bytes += strlen(objName) + 1;
  721.     if (auxName)
  722.     bytes += strlen(auxName) + 1;
  723.  
  724.     bytes = (bytes + 3) & ~3;
  725.  
  726.     if (bytes > AlBytes) {
  727.     AlBuf = malloc(4096);
  728.     if (AlBuf == NULL) {
  729.         puts("malloc failed");
  730.         exit(20);
  731.     }
  732.     AlBytes = 4096;
  733.     setmem(AlBuf, 4096, 0);
  734.     }
  735.     kn = (KeyNode *)AlBuf;
  736.     fillPtr = FillName((char *)(kn + 1), &kn->kn_Node.ln_Name, name1);
  737.     fillPtr = FillName(fillPtr, &kn->kn_Data, name2);
  738.     fillPtr = FillName(fillPtr, &kn->kn_Obj, objName);
  739.     fillPtr = FillName(fillPtr, &kn->kn_Aux, auxName);
  740.     AlBuf += bytes;
  741.     AlBytes -= bytes;
  742.     return(kn);
  743. }
  744.  
  745. char *
  746. FillName(fillPtr, pptr, name)
  747. char *fillPtr;
  748. char **pptr;
  749. char *name;
  750. {
  751.     if (name) {
  752.     strcpy(fillPtr, name);
  753.     *pptr = fillPtr;
  754.     fillPtr += strlen(name) + 1;
  755.     } else {
  756.     *pptr = NULL;
  757.     }
  758.     return(fillPtr);
  759. }
  760.  
  761. /*
  762.  *  Compile, Assemble, Generate
  763.  *
  764.  */
  765.  
  766. int
  767. Assemble(fn, srcFile, objFile)
  768. KeyNode *fn;
  769. char *srcFile;
  770. char *objFile;
  771. {
  772.     long r;
  773.     short filtered = 0;
  774.     char buf[256];
  775.  
  776.     if (DoNotExecute == 0 && strstr(fn->kn_Data, "+lconvert") && strstr(FlagsBuf, "-mD")) {
  777.     srcFile = FilterFile(srcFile);
  778.     filtered = 1;
  779.     }
  780.  
  781.     sprintf(buf, "%s %s -o %s -c", CompilerName, srcFile, objFile);
  782.     if(Symbols)strcat(buf," -s -sym");
  783.     puts(buf);
  784.     fflush(stdout);    /* SAS/C */
  785.  
  786.     r = 0;
  787.     if (DoNotExecute == 0)
  788.     r = system(buf);
  789.  
  790.     if (filtered)
  791.     remove(srcFile);
  792.  
  793.     return(r);
  794. }
  795.  
  796.  
  797. int
  798. AssembleA68(fn, srcFile, objFile)
  799. KeyNode *fn;
  800. char *srcFile;
  801. char *objFile;
  802. {
  803.     long r;
  804.     char buf[256];
  805.     short filtered = 0;
  806.  
  807.     if (DoNotExecute == 0 && strstr(fn->kn_Data, "+lconvert") && strstr(FlagsBuf, "-mD")) {
  808.     srcFile = FilterFile(srcFile);
  809.     filtered = 1;
  810.     }
  811.  
  812. /*    sprintf(buf, "%s %s -iV:include -o%s", "A68K", srcFile, objFile); */
  813.     sprintf(buf, "%s -a %s -iV:include -o%s", "HX68", srcFile, objFile);
  814.     if(Symbols)strcat(buf," -cs");
  815.     puts(buf);
  816.     fflush(stdout);    /* SAS/C */
  817.  
  818.     r = 0;
  819.     if (DoNotExecute == 0)
  820.     r = system(buf);
  821.  
  822.     if (filtered)
  823.     remove(srcFile);
  824.  
  825.     return(r);
  826. }
  827.  
  828.  
  829. int
  830. FDToLib(srcFile, objFile, aux)
  831. char *srcFile;
  832. char *objFile;
  833. char *aux;
  834. {
  835.     long r;
  836.     char buf[256];
  837.     char hfile[256];
  838.  
  839.     /*
  840.      *    locate header file (only required for registered-args tag generation)
  841.      */
  842.  
  843.     strcpy(hfile, srcFile);
  844.     if (strreplace(hfile, "_lib.fd", "_protos.h") < 0) {
  845.     printf("FD file not in *_lib.fd format: %s\n", srcFile);
  846.     return(-1);
  847.     }
  848.     if (strreplace(hfile, "/fd/", "/clib/") < 0)
  849.     strreplace(hfile, ":fd/", ":clib/");
  850.     if(Symbols == 0) {
  851.     r = sprintf(buf, "%s -n %s -h %s -o %s %s", FDToLibName, srcFile, hfile, objFile, FlagsBuf);
  852.     }
  853.     else r = sprintf(buf, "%s %s -h %s -o %s %s", FDToLibName, srcFile, hfile, objFile, FlagsBuf);
  854.     if (aux)
  855.     sprintf(buf + r, " -auto %s", aux);
  856.     puts(buf);
  857.     fflush(stdout);    /* SAS/C */
  858.  
  859.     r = 0;
  860.     if (DoNotExecute == 0)
  861.     r = system(buf);
  862.  
  863.     return(r);
  864. }
  865.  
  866. int
  867. Compile(srcFile, objFile)
  868. char *srcFile;
  869. char *objFile;
  870. {
  871.     long r;
  872.     char buf[256];
  873.  
  874.     sprintf(buf, "%s %s -o %s %s -c", CompilerName, srcFile, objFile, FlagsBuf);
  875.     if(Symbols)strcat(buf," -s -sym");
  876.     puts(buf);
  877.     fflush(stdout);    /* SAS/C */
  878.  
  879.     r = 0;
  880.     if (DoNotExecute == 0)
  881.     r = system(buf);
  882.  
  883.     return(r);
  884. }
  885.  
  886. #ifndef LATTICE
  887.  
  888. int
  889. CompareTimeStamps(name1, name2)
  890. char *name1;
  891. char *name2;
  892. {
  893.     struct stat stat1;
  894.     struct stat stat2;
  895.     long r = -1;
  896.  
  897.     if (stat(name1, &stat1) == 0) {
  898.     if (stat(name2, &stat2) == 0) {
  899.         if (stat1.st_mtime >= stat2.st_mtime) {
  900.         if (stat1.st_mtime == stat2.st_mtime) {
  901.             r = 0;
  902.         } else {
  903.             r = 1;
  904.         }
  905.         }
  906.     }
  907.  
  908.     }
  909.     return(r);
  910. }
  911.  
  912. #ifdef NOTDEF
  913.  
  914. int
  915. CompareTimeStamps(name1, name2)
  916. char *name1;
  917. char *name2;
  918. {
  919.     long lock1;
  920.     long lock2;
  921.     __aligned FileInfoBlock fib1;
  922.     __aligned FileInfoBlock fib2;
  923.     int r = -1;
  924.  
  925.     if (lock1 = Lock(name1, SHARED_LOCK)) {
  926.     if (Examine(lock1, &fib1)) {
  927.         if (lock2 = Lock(name2, SHARED_LOCK)) {
  928.         if (Examine(lock2, &fib2)) {
  929.             if (fib1.fib_Date.ds_Days >= fib2.fib_Date.ds_Days) {
  930.             if (fib1.fib_Date.ds_Days == fib2.fib_Date.ds_Days) {
  931.                 if (fib1.fib_Date.ds_Minute >= fib2.fib_Date.ds_Minute) {
  932.                 if (fib1.fib_Date.ds_Minute == fib2.fib_Date.ds_Minute) {
  933.                     if (fib1.fib_Date.ds_Tick == fib2.fib_Date.ds_Tick)
  934.                     r = 0;
  935.                     else if (fib1.fib_Date.ds_Tick > fib2.fib_Date.ds_Tick)
  936.                     r = 1;
  937.                 } else {
  938.                     r = 1;
  939.                 }
  940.                 }
  941.             } else {
  942.                 r = 1;
  943.             }
  944.             }
  945.         }
  946.         UnLock(lock2);
  947.         }
  948.     }
  949.     UnLock(lock1);
  950.     }
  951.     return(r);
  952. }
  953. #endif
  954.  
  955. #else
  956.  
  957. int
  958. CompareTimeStamps(name1, name2)
  959. char *name1;
  960. char *name2;
  961. {
  962.     long lock1;
  963.     long lock2;
  964.     FileInfoBlock *fib1 = malloc(sizeof(FileInfoBlock));
  965.     FileInfoBlock *fib2 = malloc(sizeof(FileInfoBlock));
  966.     int r = -1;
  967.  
  968.     if (lock1 = Lock(name1, SHARED_LOCK)) {
  969.     if (Examine(lock1, fib1)) {
  970.         if (lock2 = Lock(name2, SHARED_LOCK)) {
  971.         if (Examine(lock2, fib2)) {
  972.             if (fib1->fib_Date.ds_Days >= fib2->fib_Date.ds_Days) {
  973.             if (fib1->fib_Date.ds_Days == fib2->fib_Date.ds_Days) {
  974.                 if (fib1->fib_Date.ds_Minute >= fib2->fib_Date.ds_Minute) {
  975.                 if (fib1->fib_Date.ds_Minute == fib2->fib_Date.ds_Minute) {
  976.                     if (fib1->fib_Date.ds_Tick == fib2->fib_Date.ds_Tick)
  977.                     r = 0;
  978.                     else if (fib1->fib_Date.ds_Tick > fib2->fib_Date.ds_Tick)
  979.                     r = 1;
  980.                 } else {
  981.                     r = 1;
  982.                 }
  983.                 }
  984.             } else {
  985.                 r = 1;
  986.             }
  987.             }
  988.         }
  989.         UnLock(lock2);
  990.         }
  991.     }
  992.     UnLock(lock1);
  993.     }
  994.     free(fib1);
  995.     free(fib2);
  996.     return(r);
  997. }
  998.  
  999. void *
  1000. GetHead(list)
  1001. List *list;
  1002. {
  1003.     if (list->lh_Head->ln_Succ)
  1004.     return(list->lh_Head);
  1005.     return(NULL);
  1006. }
  1007.  
  1008. void *
  1009. GetSucc(node)
  1010. Node *node;
  1011. {
  1012.     if (node->ln_Succ->ln_Succ)
  1013.     return(node->ln_Succ);
  1014.     return(NULL);
  1015. }
  1016.  
  1017. #endif
  1018.  
  1019. void
  1020. CreateDirPath(buf)
  1021. char *buf;
  1022. {
  1023.     short n;
  1024.     char *p2;
  1025.  
  1026.     if ((n = strlen(buf)) && buf[n-1] == '/')
  1027.     buf[--n] = 0;
  1028.  
  1029.     if (CompareTimeStamps(buf, buf) != 0) {
  1030.     if (mkdir(buf) < 0) {
  1031.         if (p2 = strrchr(buf, '/')) {
  1032.         *p2 = 0;
  1033.         CreateDirPath(buf);
  1034.         *p2 = '/';
  1035.         mkdir(buf);
  1036.         }
  1037.     }
  1038.     }
  1039. }
  1040.  
  1041. int
  1042. strreplace(buf, findStr, repStr)
  1043. char *buf;
  1044. char *findStr;
  1045. char *repStr;
  1046. {
  1047.     char *ptr;
  1048.  
  1049.     if (ptr = strstr(buf, findStr)) {
  1050.     short l1 = strlen(findStr);
  1051.     short l2 = strlen(repStr);
  1052.  
  1053.     if (l1 < l2)
  1054.         movmem(ptr, ptr + (l2 - l1), strlen(ptr) + 1);
  1055.     else if (l1 > l2)
  1056.         movmem(ptr, ptr - (l1 - l2), strlen(ptr) + 1);
  1057.     strncpy(ptr, repStr, l2);
  1058.     return(0);
  1059.     } else {
  1060.     return(-1);
  1061.     }
  1062. }
  1063.  
  1064. void
  1065. DicePrefix(char *buf, char *av0, char *app)
  1066. {
  1067.     char *ptr;
  1068.     short n = 0;
  1069.  
  1070.     for (ptr=av0+strlen(av0); ptr >= av0 && *ptr != '/' && *ptr != ':'; --ptr)
  1071.     ;
  1072.     ++ptr;
  1073.     if (av0 = strchr(ptr, '_')) {
  1074.     n = av0 - ptr + 1;
  1075.     strncpy(buf, ptr, n);
  1076.     }
  1077.     strcpy(buf + n, app);
  1078. }
  1079.  
  1080. char *
  1081. FilterFile(srcFile)
  1082. char *srcFile;
  1083. {
  1084.     FILE *fi;
  1085.     FILE *fo;
  1086.     char buf[256];
  1087.     static char tmpFile[256];
  1088.  
  1089.     strcpy(tmpFile, tmpnam(NULL));
  1090.     strcat(tmpFile, ".a");
  1091.  
  1092.     if (fo = fopen(tmpFile, "w")) {
  1093.     if (fi = fopen(srcFile, "r")) {
  1094.         while (fgets(buf, sizeof(buf), fi)) {
  1095.         char *ptr;
  1096.  
  1097.         while ((ptr = strstr(buf, "(A4)")) || (ptr = strstr(buf, "(a4)"))) {
  1098.             movmem(ptr + 4, ptr, strlen(ptr + 3));
  1099.         }
  1100.         fputs(buf, fo);
  1101.         }
  1102.         fclose(fi);
  1103.     }
  1104.     fclose(fo);
  1105.     }
  1106.     return(tmpFile);
  1107. }
  1108.  
  1109.